#include "SoftSpi.h"


#define SoftSpi_BitWrite(port,pin,val) do { \
    if(val) *port |=  1u<<pin ;\
    else *port &=  ~(1u<<pin) ;\
} while (0)

#define SoftSpi_PinSet(port,pin) do { \
    *port |=  1u<<pin ;\
} while (0)

#define SoftSpi_PinReset(port,pin) do { \
    *port &=  ~(1u<<pin) ;\
} while (0)

#define SoftSpi_PinGet(port, pin)  ((*port>>pin)&0x1u)

void SoftSpi_Init(
    SPI_t *spi ,
    volatile uint32_t * _port ,     
    int8_t _clock_pin,
    int8_t _mosi_pin ,
    int8_t _miso_pin ,
    int8_t _cpol , 
    int8_t _cpha ,
    uint8_t _delay_ticks 
) 
{
    spi->port = _port ;
    spi->clock_pin =  _clock_pin ;
    spi->mosi_pin  =  _mosi_pin  ;
    spi->miso_pin  =  _miso_pin ;
    spi->delay_ticks = _delay_ticks ;
    spi->cpol = _cpol ;
    spi->cpha = _cpha ;
    SoftSpi_BitWrite(spi->port , spi->clock_pin , spi->cpol) ;
}


uint8_t SoftSpi_Write(SPI_t *spi,volatile uint8_t _value  ) {
    uint8_t input_data = 0u;
    uint8_t bit_mask =   0x80 ;
    uint8_t cpol =   spi->cpol ;
    SoftSpi_BitWrite(spi->port, spi->clock_pin,cpol);
    if(cpol) *spi->port |=  1u<< spi->clock_pin;
    for(int8_t i = 0; i < 8; i++) {
        //输出数据
        if(_value & bit_mask) SoftSpi_PinSet(spi->port,spi->mosi_pin) ; 
        else  SoftSpi_PinReset(spi->port,spi->mosi_pin) ;
        bit_mask = bit_mask>>1;
        //if(spi->cpha==0)Serv_DelayTik(spi->delay_ticks);

        //第一个条边沿
        SoftSpi_BitWrite(spi->port, spi->clock_pin,cpol^=0x01);
        //if(spi->cpha==1)Serv_DelayTik(spi->delay_ticks);
        
        input_data |= (SoftSpi_PinGet(spi->port, spi->miso_pin) << (0x07-i));
       // if(spi->cpha==0)Serv_DelayTik(spi->delay_ticks);
        //第二个边沿
        SoftSpi_BitWrite(spi->port, spi->clock_pin,cpol^=0x01);
        //if(spi->cpha==1)Serv_DelayTik(spi->delay_ticks);

    }
    return input_data;
}

// void SoftSpi_BitWrite(volatile uint32_t * _port, uint8_t _pin , int8_t _val) {
//     if(_val) {
//         *_port |= 1u << _pin;
//     } else {
//         *_port &= ~(1u << _pin);
//     }
// }

// uint32_t readBit(volatile uint32_t * _port, uint8_t _pin) {
//     return (*_port >> _pin) & 1u;
// }